package com.tuniondata.netty.server;

import com.tuniondata.netty.bean.RpcMessage;
import com.tuniondata.netty.common.protocol.Protocol;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApiServerHandler extends SimpleChannelInboundHandler {
    private static final Logger log = LoggerFactory.getLogger(ApiServerHandler.class);
    // 控制超时时间
    private int loss_connect_time = 0;

    @Override
    protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("服务器收到消息, {}", msg.toString());
        NettyChannelMap.add(ctx.channel().id().asLongText(), (SocketChannel) ctx.channel());
        RpcMessage rpcMessage = (RpcMessage) msg;
        Protocol protocol = rpcMessage.getProtocol();
        String mtp = protocol.getMessageType();
        log.info("message type: {}", mtp);
        RpcMessage response = null;
        try {
            ApiProcessor processor = new ApiProcessor();
            response = processor.process(rpcMessage);
            log.info("response {}", response);
            if (response == null) {
                log.debug("mti:{} not supported", mtp);
                protocol.setBody("");
            }
        } catch (Exception e) {
            log.error("process exception", e);
            protocol.setBody("");
        }
        ctx.writeAndFlush(response);
        //释放
        ReferenceCountUtil.release(msg);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                loss_connect_time++;
                System.out.println("10 秒没有接收到客户端的信息了");
                if (loss_connect_time > 3) {
                    NettyChannelMap.remove((SocketChannel) ctx.channel());
                    ctx.channel().close();
                }
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        NettyChannelMap.remove((SocketChannel) ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("server caught exception", cause);
        NettyChannelMap.remove((SocketChannel) ctx.channel());
        ctx.close();
    }
}
